package com.db.bankapp.domain;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @ThreadSafe
 * Represents bank client
 */
public class Client implements Serializable {
    private final AtomicLong idSeq = new AtomicLong();
    private final String name;
    private final Gender sex;
    private final Set<Account> accounts = new LinkedHashSet<>();

    Client(String name, Gender sex, Account account) {
        this.name = name;
        this.sex = sex;
        if (account != null) {
            accounts.add( account);
        }
    }

    Client(String name, Gender sex) {
        this(name, sex, null);
    }

    /**
     * Adds clients account
     * @param account to add
     * @throws java.lang.NullPointerException when account is null
     */
    public void addAccount(Account account) {
        if (account == null) {
            throw new NullPointerException("Account should not be null!");
        }
        accounts.add( account);
    }

    /**
     * Returns copy of clients accounts
     * @return clients account
     */
    public Collection<Account> getAccounts() {
        return Collections.unmodifiableSet(accounts);
    }

    /**
     * Returns account by id
     * @param id of account to return
     * @return account
     */
    public Account getAccount(int id) {
        return (Account) this.getAccounts().toArray()[id];
    }

    /**
     * Returns and prints client salutation
     * @return client salutation
     */


    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof Client )) return false;
        if (o instanceof Client) {
            return this.name.equals(((Client) o).name) && this.sex.equals(((Client) o).sex) && this.getAccounts().equals(((Client) o).getAccounts());
        }
        return false;
    }
    @Override
    public int hashCode() {
        int result=17;
        result = result*31+this.name.hashCode();
        result=result*31+ this.getAccounts().hashCode();
        result =result*31 + this.sex.hashCode();
        return result;
    }

    public String toString() {
        StringBuffer salutation = new StringBuffer(sex.getSalutations()).append(name).append("with " + this.getAccounts().size() + " accounts");

//        System.out.println(salutation); // it shouldn't print anything since its get
        return salutation.toString();
    }

    public int getSumOverdraft()  {
        int sum=0;
        for (Account account: this.getAccounts()) {
            if (account instanceof CheckingAccount) {
                sum+=((CheckingAccount) account).getOverdraft();
            }
        }
        return sum;
    }

}

